package io.adrainty.bolee.framework.web.interceptor;

import cn.dev33.satoken.stp.StpLogic;
import io.adrainty.bolee.framework.commons.constants.GlobalOauth2Constants;
import io.adrainty.bolee.framework.commons.user.SubjectContentUtil;
import io.adrainty.bolee.framework.commons.user.UserEntity;
import io.adrainty.bolee.framework.commons.utils.StpKit;
import io.adrainty.bolee.framework.web.utils.RequestContextUtil;
import io.adrainty.bolee.security.models.constants.CompanyConstants;
import io.adrainty.bolee.security.models.entity.CompanyEntity;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.List;
import java.util.Objects;

/**
 * @author AdRainty
 * @version V1.0.0
 * @since 2025/8/4 上午12:37
 */

@Slf4j
public class WebAuthInterceptor implements HandlerInterceptor {

    @Resource
    private RedissonClient redissonClient;

    private final List<String> ignoreUrl;

    public WebAuthInterceptor(List<String> ignoreUrl) {
        this.ignoreUrl = ignoreUrl;
    }

    @Override
    public boolean preHandle(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull Object handler) {
        if (ignoreUrl.contains(request.getRequestURI())) {
            return true;
        }

        StpLogic stpLogic = checkDomain(request);
        String tokenValue = stpLogic.getTokenValue();
        if (StringUtils.isNotBlank(tokenValue)) {
            RBucket<UserEntity> userVORBucket = redissonClient.getBucket(GlobalOauth2Constants.USER_TOKEN_CACHE + tokenValue);
            UserEntity userVO = userVORBucket.get();
            if (userVO == null) return true;

            // 放入当前线程中：用户当前的web直接获得userVO使用
            SubjectContentUtil.setUserVO(userVO);
            // 下游传递userToken
            SubjectContentUtil.setUserToken(tokenValue);
            // 下游传递companyNo
            SubjectContentUtil.setCompanyNo(userVO.getCompanyNo());
            // 下游传递companyNo
            SubjectContentUtil.setDataSecurityVO(userVO.getDataSecurityVO());
        }

        return true;
    }

    private StpLogic checkDomain(HttpServletRequest request) {
        String remoteHost = RequestContextUtil.getRemoteHost(request);
        String key = CompanyConstants.COMPANY_WEBSITE_CACHE_KEY + remoteHost;
        RBucket<CompanyEntity> bucket = redissonClient.getBucket(key);
        CompanyEntity companyEntity = bucket.get();
        if (Objects.isNull(companyEntity)) {
            return StpKit.USER;
        }

        if (remoteHost.equals(companyEntity.getAppSite())) {
            return StpKit.CUSTOMER;
        }
        return StpKit.USER;
    }

    @Override
    public void afterCompletion(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull Object handler, Exception ex) {
        //移除当前线程中的参数
        SubjectContentUtil.removeUserVO();
        SubjectContentUtil.removeUserToken();
        SubjectContentUtil.removeCompanyNo();
        SubjectContentUtil.removeDataSecurityVO();
    }

}
